Configuration, constants, and model creation.
Prefix used to infer Fireworks from fully-qualified IDs.
Model spec (provider:model) used by the Auto approval-mode classifier.
Unset (the default) reuses the main agent model, preserving the historical
behavior. A provider:model value points the authorization classifier at a
separate — typically faster and cheaper — model without changing the model that
writes code. The classifier is a security control: a model that cannot be
resolved (bad spec, missing credentials, uninstalled provider package) never
falls back to the main model — reviewed actions are denied, and repeated
failures escalate to your approval. Also settable via [models].auto_classifier
in config.toml and --auto-classifier-model.
This is user-controlled process env, not a repo file: a committed project
.env cannot set it (see config._PROJECT_DOTENV_DENIED_ENV_KEYS), so a cloned
repository cannot point the review that authorizes its own tool calls at a weaker
model. Only the shell, the launch environment, or the global ~/.deepagents/.env
can.
Seconds the Auto approval-mode classifier may take to review one batch.
Raise this when reviews time out on a slow or heavily loaded classifier model:
a batch that misses the deadline is denied as classifier_unavailable, so the
tool call does not run and repeated misses escalate to your approval. This
covers the wait for a verdict only — the separate budget for building the
classifier model (cold provider import, credential bootstrap), which denies with
"could not be built within 30s", is fixed. Values outside 1-300 seconds are
ignored in favor of the next config source, so the deadline can never be
removed. Also settable via [models].auto_classifier_timeout in config.toml.
Resolved once per dcode start, so a change takes effect on the next launch.
Like AUTO_CLASSIFIER_MODEL, a committed project .env cannot set it (see
config._PROJECT_DOTENV_DENIED_ENV_KEYS).
Comma-separated project MCP server names to dangerously pre-approve by name.
This is an explicit process-wide escape hatch. Servers named here load from an
otherwise-untrusted project .mcp.json without prompting (they are omitted from
the interactive approval prompt), while non-listed servers still require
approval (they go through the prompt, and stay dropped only on the
non-interactive or denied paths). Like
DISABLED_PROJECT_MCP_SERVERS, this is user-controlled process env, not a repo
file, so it does not weaken the user-level-only trust boundary (a committed
project .env cannot set it; see config._PROJECT_DOTENV_DENIED_ENV_KEYS).
This dangerous contract is name-based: a different project, command change, or
URL change under the same server name still matches.
This process-wide allowlist and the scoped
[mcp].enabled_project_server_approvals TOML approvals are independent grants.
Setting this variable, including to an empty value, does not suppress remembered
project approvals. (DISABLED_PROJECT_MCP_SERVERS instead unions with its
TOML list, so a deny is never silently emptied.)
Comma-separated project MCP server names to always reject by name.
A user-level equivalent of [mcp].disabled_project_servers.
Rejection wins over approval: a name listed here is dropped even when it also
appears in DANGEROUSLY_ENABLE_PROJECT_MCP_SERVERS or in a scoped
[mcp].enabled_project_server_approvals entry, and even when the project config
is otherwise trusted. Unlike the enabled list, this env var unions with
(rather than replaces) [mcp].disabled_project_servers — denies accumulate
across sources, so neither can silently empty a deny set in the other. This is
process env the user controls, not a repo file, so it does not weaken the
user-level-only trust boundary: a committed project .env is blocked from
setting it (see config._PROJECT_DOTENV_DENIED_ENV_KEYS); only the user's
shell, launch env, or global ~/.deepagents/.env can.
Hide version and local-install details in the splash screen when enabled.
Default LangGraph recursion_limit for the main agent.
Single source of truth shared by the runtime.recursion_limit option, the
config.config runnable-config default, and resolve_recursion_limit. Raised
above the LangGraph/SDK default (25) to accommodate deeply nested agent graphs
in long-running sessions without hitting GRAPH_RECURSION_LIMIT.
Canonical LangSmith SaaS endpoint for the US region (the SDK default).
Canonical LangSmith SaaS endpoint for the EU region.
Maps each non-normal mode to its trigger character.
Maps each non-normal mode to its display glyph shown in the prompt/UI.
Glyph set for terminals with full Unicode support.
Glyph set for terminals limited to 7-bit ASCII.
Character limit for tool argument values in the UI.
Longer values are truncated with an ellipsis by truncate_value
in tool_display.
Default LangGraph runnable config for the main agent.
Sets recursion_limit to RECURSION_LIMIT_DEFAULT (2000) to accommodate deeply
nested agent graphs in long-running sessions without hitting the default
LangGraph ceiling. The literal lives in config_manifest so the default is
defined in exactly one place. This value is the fallback: create_cli_agent
resolves the effective limit at agent-build time via resolve_recursion_limit,
which honors the --recursion-limit CLI flag, the DEEPAGENTS_CODE_RECURSION_LIMIT
env var, and [runtime].recursion_limit in config.toml.
Fixed ls_agent_purpose literal identifying the coding-agent trace class.
Stable ls_integration id for this plugin (unchanged for backward-compat).
User-facing ls_agent_runtime name.
Version of the coding-agent trace-metadata contract this build emits.
Sentinel value returned by parse_shell_allow_list for --shell-allow-list=all.
Strictly read-only PTC allowlist for interpreter_ptc="safe".
Limited to tools that are not in _add_interrupt_on() to begin with, so
exposing them through PTC does not introduce a new HITL bypass. Network
tools (web_search, fetch_url), subagent dispatch (task), shell
execution (execute), and file writes (write_file, edit_file, MCP
write tools) are deliberately excluded — they are HITL-gated outside the
REPL, and PTC bypasses interrupt_on, so including them would silently
escalate privileges. Users who need network or subagent access from inside
the REPL must list those tools explicitly (which signals intent at config
time) or use interpreter_ptc="all" with the unsafe acknowledgement.
Sentinel string for interpreter_ptc="all" — resolved at agent-build time
from the live tool list. Requires interpreter_ptc_acknowledge_unsafe=True
when auto_approve is False.
Sentinel string for interpreter_ptc="safe" — expanded from
INTERPRETER_PTC_SAFE_PRESET.
Internal carrier key for the --max-retries CLI flag.
cli_main stashes the flag value under this key in the model_params dict it
forwards to the run, and create_model pops it before constructing the model.
This lets the CLI value ride the existing model_params/extra_kwargs carrier
to the one place that authoritatively resolves the provider, where it can be
folded under the provider's resolved retry-param name (see
_resolve_retry_param_name) rather than a hardcoded max_retries.
The key is internal-only: it is popped before reaching any model constructor and is never serialized or surfaced to users. It is deliberately unlikely to collide with a real constructor kwarg name.
Literal substrings that indicate shell injection risk.
Used by contains_dangerous_patterns to reject commands that embed arbitrary
execution via redirects, substitution operators, or control characters — even
when the base command is on the allow-list.
Read-only commands auto-approved in non-interactive mode.
Only includes readers and formatters — shells, editors, interpreters, package
managers, network tools, archivers, and anything on GTFOBins/LOOBins is
intentionally excluded. File-write and injection vectors are blocked separately
by DANGEROUS_SHELL_PATTERNS.
Return whether env var name is set to a recognizably truthy value.
Unlike bool(os.environ.get(name)), this does not treat "0" or
"false" as enabled. Use this for on/off flags where the user would
reasonably expect VAR=0 to mean "disabled".
Resolve the current git branch with a filesystem-first strategy.
Resolve a LangSmith endpoint shorthand to its canonical URL.
Maps the case-insensitive region aliases us/eu to the LangSmith SaaS
endpoints so the CLI --base-url flag and the TUI /auth prompt share one
decode. Any other non-empty value is returned stripped and unchanged (a
self-hosted or proxied URL); empty input returns an empty string.
Return whether value is a non-empty http/https URL with a host.
Guards the LangSmith endpoint so a stored API key is never paired with a non-HTTP, malformed, or schemeless value that could route trace ingestion (and the key) somewhere unintended.
Return and clear the pending orphaned-tracing notice, if any.
Restore caller tracing flags in an environment passed to user code.
Restore caller tracing API keys in an environment passed to user code.
Reverts both bootstrap overwrites of the canonical LangSmith key — the
DEEPAGENTS_CODE_-prefixed override and the /auth-stored key — so shell
subprocesses receive the caller's own key rather than the agent's session
key. See original_tracing_api_keys for the rationale; this mirrors
restore_user_tracing_env, which does the same for tracing flags.
Apply a /auth-stored LangSmith key, tracing, and redaction now.
Return the longest mode prefix and mode for text, if any.
Longer prefixes win so multi-character triggers like !! are matched
before their single-character prefixes (!).
Get the glyph set for the current charset mode.
Reset the glyphs and charset-mode caches (for testing).
Check whether the terminal is in ASCII charset mode.
Convenience wrapper so widgets can branch on charset without importing
both _detect_charset_mode and CharsetMode.
Return the terminal-appropriate label for the newline keyboard shortcut.
Prefers Shift+Enter when the terminal is known to support the kitty
keyboard protocol, either via conservative terminal-identity heuristics
or the DEEPAGENTS_CODE_KITTY_KEYBOARD override. Falls back to
Option+Enter on macOS and Ctrl+J elsewhere — both survive legacy
terminals that strip the shift modifier from Enter.
Get the appropriate banner for the current charset mode.
Build the shared coding-agent-v1 trace-metadata block.
Implements the coding-agent-v1 contract for Deep Agents Code:
one helper that stamps the identity block, plugin/runtime versions, turn
markers, and repo/git/cwd attribution. The six identity/version keys and
thread_id are always present; the optional keys whose value is unknown are
omitted (per the contract), so callers can pass None for any of them.
Because Deep Agents Code is itself the runtime — there is no separate CLI
package — ls_integration_version and ls_agent_runtime_version both come
from the deepagents-code package version (__version__). The underlying
deepagents SDK version is surfaced separately as
dcode_client_deepagents_version by build_stream_config.
Scope-restricted contract keys are intentionally NOT produced here:
approval_policy (root/interrupted only) and ls_subagent_id /
ls_subagent_type (subagent only). This metadata propagates trace-wide
through the LangGraph stream config (and, for subagents, the per-key config
merge of langgraph#7926 / deepagents#3634), so any key placed here lands on
every descendant run. Emitting a run-type-scoped key would therefore leak it
onto run types outside its contract appliesTo set — a hard validator
failure — and the LangGraph runtime exposes no clean per-run-type metadata
seam to scope them. See build_stream_config for the full rationale.
Build the LangGraph stream config dict.
Stamps the shared coding-agent-v1 trace-metadata contract via
build_coding_agent_metadata — identity block, plugin/runtime versions,
turn markers, and repo/git/cwd attribution — onto metadata. Metadata set
here propagates trace-wide to every run in the graph (root, llm, tool, and
subagent subgraphs), which is exactly what the contract's "always" and
"where-known" keys require, so the helper output is stamped once here.
Scope-restricted contract keys are deliberately not emitted. approval_policy
(root/interrupted only) and ls_subagent_id / ls_subagent_type (subagent
only) cannot live in this trace-wide metadata: LangGraph propagates each key
to all descendant runs (per-key config merge, langgraph#7926 /
deepagents#3634), so they would leak onto run types outside their contract
appliesTo set and fail validation. This runtime exposes no clean
per-run-type metadata seam to scope them, so they are omitted by design
rather than leaked. (Subagent runs still inherit the parent/root thread_id
and all required keys, satisfying the contract's grouping rule.)
Also injects the dcode version into metadata["lc_versions"] so LangSmith
traces can be correlated with specific releases. create_deep_agent supplies
the SDK version through the compiled graph config, and LangChain merges
nested metadata dictionaries so both versions survive at stream time.
Also records dcode_client_deepagents_version as a dcode-client diagnostic.
This describes the Deep Agents package installed alongside the TUI, which
can differ from a remote graph's Deep Agents runtime version. Editable
installs carry an +editable suffix, matching how the SDK stamps
lc_versions["deepagents"]; for sibling monorepo packages that suffix
identifies workspace HEAD relative to the pinned published SDK baseline.
Also records dcode_experimental=True when DEEPAGENTS_CODE_EXPERIMENTAL
is enabled, so experimental runs are filterable in trace metadata.
Also records dcode_auto_approve=True when auto-approve ("YOLO") mode is
active, so runs that ran tools without HITL approval are filterable in trace
metadata. This is a diagnostic key, not the contract-scoped approval_policy
key (see above), so it is safe to stamp trace-wide.
Also records dcode_term_program from TERM_PROGRAM when that is non-empty
after stripping, so traces are groupable by launch environment (e.g.
"iTerm.app", "vscode", "Apple_Terminal"). Blank values are treated as unset
to match every other reader of this variable — some shells export
TERM_PROGRAM="" rather than leaving it unset, and terminals that never set
it (Windows Terminal, ssh, the Linux console) omit the key entirely rather
than forming a junk grouping bucket. This is a diagnostic key, not part of
the contract.
Parse shell allow-list from string.
Check if a command contains dangerous shell patterns.
These patterns can be used to bypass allow-list validation by embedding
arbitrary commands within seemingly safe commands. The check includes
both literal substring patterns (redirects, substitution operators, etc.)
and regex patterns for bare variable expansion ($VAR) and the background
operator (&).
Check if a shell command is in the allow-list.
The allow-list matches against the first token of the command (the executable name). This allows read-only commands like ls, cat, grep, etc. to be auto-approved.
When allow_list is the SHELL_ALLOW_ALL sentinel, all non-empty commands
are approved unconditionally — dangerous pattern checks are skipped.
SECURITY: For regular allow-lists, this function rejects commands containing dangerous shell patterns (command substitution, redirects, process substitution, etc.) BEFORE parsing, to prevent injection attacks that could bypass the allow-list.
Resolve the LangSmith project name if tracing is configured.
Checks for the required API key and tracing environment variables.
When both are present, resolves the project name with priority:
settings.deepagents_langchain_project (from
DEEPAGENTS_CODE_LANGSMITH_PROJECT), then LANGSMITH_PROJECT from the
environment (note: this may already have been overridden at bootstrap time
to match DEEPAGENTS_CODE_LANGSMITH_PROJECT), then 'deepagents-code'.
Report an empty prefixed override that is suppressing a LangSmith key.
/trace shows a generic "not configured" hint whenever no key resolves, but
a common footgun is exporting DEEPAGENTS_CODE_LANGSMITH_API_KEY= (empty).
A present-but-empty prefixed variable suppresses a key two ways: per
resolve_env_var's precedence it shadows the canonical env variable
directly, and -- because apply_stored_service_credentials skips the /auth
bridge onto LANGSMITH_API_KEY whenever the prefixed var is present -- it
also keeps a /auth-stored key from ever reaching the environment. Either
way tracing silently stays off even though a key is available. Detecting this
lets callers name the offending variable instead of sending the user to
/auth.
Only an override that actually gates the effective key is reported. If a
key already resolves under the normal LANGSMITH_API_KEY-before-
LANGCHAIN_API_KEY precedence, tracing is off for some other reason (a
missing tracing flag), no override is to blame, and nothing is reported.
Otherwise each override is checked against the specific key it suppresses, so
the returned name is one that, once unset, actually lets a key resolve: its
canonical variant carries a value, or -- for LANGSMITH_API_KEY, the var
/auth bridges its stored key onto -- a stored key exists. When several
overrides qualify, the first in _TRACING_API_KEY_ENV_VARS order is
returned.
Return whether LangSmith secret redaction is enabled for agent traces.
Return whether the agent should proactively save learnings to memory.
Resolves the memory.auto_save option from env/config.toml, defaulting to
enabled. When disabled, memory is still loaded into context but the agent is
told not to auto-save.
Return whether Shift+Tab may enter unrestricted YOLO mode.
Resolves the startup.yolo_switcher option from env/config.toml,
defaulting to enabled. When disabled, the interactive cycle stays Manual /
Auto only (or Manual alone when Auto is ineligible). Sessions already in
YOLO (for example via --yolo) can still leave it with Shift+Tab.
Return whether OpenAI model calls should carry a per-thread cache key.
Resolves the models.openai_prompt_cache_key option from env/config.toml,
defaulting to enabled. When disabled, ConfigurableModelMiddleware stops
injecting the thread ID as an OpenAI prompt_cache_key (a user-supplied key
is still forwarded). This is the opt-out for OpenAI-compatible endpoints that
reject unknown request fields.
Resolve the Auto classifier spec and any reason it was ignored.
Reads the models.auto_classifier option from env/config.toml. None
means the classifier inherits the main agent model, which is the historical
behavior and the default.
A configured-but-unusable value (blank, or a non-string such as
auto_classifier = 3, which resolve_scalar drops to the default) silently
reverts authorization review to the main agent model — the agent grading its
own actions. The caller gets a description so it can say so on a surface the
user actually reads; a log line alone is not that surface.
Resolve the model spec the Auto approval classifier should use.
Resolve whether Auto mode applies generated goal criteria without review.
Install the LangSmith SDK secret anonymizer for active agent tracing.
This is a fail-closed security control: when redaction is requested but the redacting client cannot be installed, tracing is disabled rather than risk uploading unredacted secrets to LangSmith.
Extra LangSmith project names to dual-write agent traces to.
Parses DEEPAGENTS_CODE_LANGSMITH_REPLICA_PROJECTS (comma-separated) into a
de-duplicated, order-preserving list.
The single extra LangSmith project to mirror agent runs to, if configured.
dcode agent runs execute inside the LangGraph server subprocess, so the only
way to mirror them to another project is the server's own replica path: the
SDK forwards a langsmith_tracing project in the run-create request, and the
server wraps the run in a tracing_context whose write replicas are that
project plus the server's primary project. Client-side callbacks and
tracing_context(replicas=...) cannot reach the run because it is created
server-side, not in the app process.
Implementation detail (subject to change): as of langgraph-api 0.10.0 this
happens in langgraph_api.stream and langgraph_api.models.run.
The server mirrors to exactly one extra project, so when
DEEPAGENTS_CODE_LANGSMITH_REPLICA_PROJECTS lists several, only the first is
used and the rest are dropped with a warning.
Summarize LangSmith tracing configuration for diagnostics.
Reads only the local environment and the active LangSmith profile; never
contacts the network and never exposes secret values. All fields are
resolved prefix-/profile-aware so the report matches what the runtime does
after bootstrap, even though dcode doctor runs before it.
Fetch the LangSmith project URL, raising on any failure.
Successful results are cached at module level so repeated calls do not make additional network requests.
The network call runs in a daemon thread with a hard timeout of
_LANGSMITH_URL_LOOKUP_TIMEOUT_SECONDS, so this function blocks the
calling thread for at most that duration even if LangSmith is unreachable.
Fetch the LangSmith project URL, returning None on any failure.
Thin back-compat wrapper around fetch_langsmith_project_url_or_raise
for passive callers (status banners, non-interactive output) that just
want a URL-or-nothing answer. Interactive callers that need to tell the
user why the lookup failed should use the raising variant directly.
Build a full LangSmith thread URL if tracing is configured.
Combines get_langsmith_project_name and fetch_langsmith_project_url
into a single convenience helper.
Build a LangSmith thread URL only when its project URL is cached.
This non-blocking variant lets transient UI surfaces render a previously resolved link immediately without repeating or scheduling another lookup.
Reset the LangSmith URL cache (for testing).
Get the default coding agent instructions.
These are the immutable base instructions that cannot be modified by the agent. Long-term memory (AGENTS.md) is handled separately by the middleware.
Auto-detect provider from model name.
Intentionally duplicates a subset of LangChain's
_attempt_infer_model_provider because we need to resolve the provider
before calling init_chat_model in order to:
init_chat_model.Create a chat model.
Uses init_chat_model for standard providers, or imports a custom
BaseChatModel subclass when the provider has a class_path in config.
Supports provider:model format (e.g., 'openai:gpt-5.5')
for explicit provider selection, or bare model names for auto-detection.
Validate that the model has required capabilities for deepagents.
Checks the model's profile (if available) to ensure it supports tool calling, which is required for agent functionality. Issues warnings for models without profiles or with limited context windows.
Parsed origin remote attribution for coding-agent-v1 traces.
A NamedTuple so callers can still unpack positionally or index, while the
field names keep the slot order from being load-bearing at every call site.
Character set mode for TUI display.
Character glyphs for TUI display.
Global settings and environment detection for deepagents-code.
This class is initialized once at startup and provides access to:
Why /trace found no LangSmith key, when an empty override is involved.
Distinguishes the three states the caller renders differently: a specific
empty override is suppressing an available key (shadowing_var), the
credential store could not be read so a stored key can't be ruled out
(store_unreadable), or neither (both fields falsy -- the generic "not
configured" hint applies).
Offline snapshot of LangSmith tracing configuration for diagnostics.
Carries only presence/identity facts — never API keys or other secret
values — so it is safe to render in dcode doctor output.
Base class for typed LangSmith project URL lookup failures.
Concrete subclasses (LangSmithImportError, LangSmithLookupTimeoutError,
LangSmithApiError) let interactive callers like /trace show the user
the actual cause instead of collapsing every failure into a generic
"could not reach LangSmith" message.
The langsmith package is not installed.
The LangSmith project URL lookup exceeded its hard timeout.
The LangSmith SDK call raised — auth, 404, network, etc.
Wraps the underlying SDK exception in __cause__.
The LangSmith project does not exist yet (lookup returned 404).
Projects are created lazily on the first ingested trace, so this is expected before any run has flushed and should be surfaced as an informational message rather than an error.
Result of creating a chat model, bundling the model with its metadata.
This separates model creation from settings mutation so callers can decide when to commit the metadata to global settings.